 /// @file InterOpDimension.h
 /// @brief InterOpDimension 
 /// @copyright Copyright (c) 2025  Hefei Jiushao Intelligent Technology Co., Ltd. All rights reserved.
 /// @createtime 2025-04-07

#ifndef INTEROPDIMENSION_H
#define INTEROPDIMENSION_H
#include "InterOpPMIBase.h"
#include "InterOpPMINote.h"
#include "nlohmann/json.hpp"

namespace  AMCAX::Exchange::InterOp::PMI {

enum class PMIDimensionMainType
{
	DMT_Unknown,	  /**< DMT_Unknown */
	DMT_Basic,	  /**< DMT_Basic */
	DMT_Reference,  /**< DMT_Reference */
	DMT_Tolerance,  /**< DMT_Tolerance */
	DMT_CoordDim,	  /**< DMT_CoordDim */
	DMT_HoleCallout /**< DMT_HoleCallout */
};

enum class PMIDimensionSubType
{
	UNKNOWN,
	Distance,				 /**< Distance */
	DistanceOffset,		 /**< DistanceOffset */
	Length,				 /**< Length */
	Length_OR_Distance,	 /**< Length_OR_Distance */
	LengthCurvilinear,	 /**< LengthCurvilinear */
	Angle,				 /**< Angle */
	Radius,				 /**< Radius */
	RadiusTangent,		 /**< RadiusTangent */
	RadiusCylinder,		 /**< RadiusCylinder */
	RadiusEdge,			 /**< RadiusEdge */
	Diameter,				 /**< Diameter */
	DiameterTangent,		 /**< DiameterTangent */
	DiameterCylinder,		 /**< DiameterCylinder */
	DiameterEdge,			 /**< DiameterEdge */
	DiameterCone,			 /**< DiameterCone */
	Chamfer,				 /**< Chamfer */
	Slope,				 /**< Slope */
	DimGDT,				 /**< DimGDT */
	DimDatumFeature,		 /**< DimDatumFeature */
	DimDatumTarget,		 /**< DimDatumTarget */
	DimBalloon,			 /**< DimBalloon */
	No_Dim,				 /**< No_Dim */
	AngleArc,				 /**< AngleArc */
	LengthCircular,		 /**< LengthCircular */
	Fillet,				 /**< Fillet */
	CoordDimension_2D,	 /**< CoordDimension_2D */
	CoordDimension_3D		 /**< CoordDimension_3D */
};

enum class PMIUnit
{
	DimUnitNone,		 /**< DimUnitNone */
	DimUnitMM,		 /**< DimUnitMM */
	DimUnitINCH,		 /**< DimUnitINCH */
	DimUnitMETER,		 /**< DimUnitMETER */
	DimUnitCM,		 /**< DimUnitCM */
	DimUnitKM,		 /**< DimUnitKM */
	DimUnitFOOT,		 /**< DimUnitFOOT */
	DimUnitF_I_F64,	 /**< DimUnitF_I_F64 */
	DimUnitF_I_F16,	 /**< DimUnitF_I_F16 */
	DimUnitF_I_DEC,	 /**< DimUnitF_I_DEC */
	DimUnitDEGREE,	 /**< DimUnitDEGREE */
	DimUnitMINUTE,	 /**< DimUnitMINUTE */
	DimUnitSECOND,	 /**< DimUnitSECOND */
	DimUnitRADIAN,	 /**< DimUnitRADIAN */
	DimUnitGRADE		 /**< DimUnitGRADE */
};

enum class PMIDimensionFakeType
{
	FakeUnknown,		 /**< FakeUnknown */
	FakeNumeric,		 /**< FakeNumeric */
	FakeText			 /**< FakeText */
};				

enum class PMIArrowSymbol
{
	NOTUSED,				 /**< NOTUSED */
	CROSS,				 /**< CROSS */
	PLUS,					 /**< PLUS */
	CONCENTRIC,			 /**< CONCENTRIC */
	COINCIDENT,			 /**< COINCIDENT */
	FULLCIRCLE,			 /**< FULLCIRCLE */
	FULLSQUARE,			 /**< FULLSQUARE */
	STAR,					 /**< STAR */
	DOT,					 /**< DOT */
	SMALLDOT,				 /**< SMALLDOT */
	MISC1,				 /**< MISC1 */
	MISC2,				 /**< MISC2 */
	FULLCIRCLE2,			 /**< FULLCIRCLE2 */
	FULLSQUARE2,			 /**< FULLSQUARE2 */
	OPEN_ARROW,			 /**< OPEN_ARROW */
	UNFILLED_ARROW,		 /**< UNFILLED_ARROW */
	BLANKED_ARROW,		 /**< BLANKED_ARROW */
	FILLED_ARROW,			 /**< FILLED_ARROW */
	UNFILLED_CIRCLE,		 /**< UNFILLED_CIRCLE */
	BLANKED_CIRCLE,		 /**< BLANKED_CIRCLE */
	FILLED_CIRCLE,		 /**< FILLED_CIRCLE */
	CROSSED_CIRCLE,		 /**< CROSSED_CIRCLE */
	BLANKED_SQUARE,		 /**< BLANKED_SQUARE */
	FILLED_SQUARE,		 /**< FILLED_SQUARE */
	BLANKED_TRIANGLE,		 /**< BLANKED_TRIANGLE */
	FILLED_TRIANGLE,		 /**< FILLED_TRIANGLE */
	MANIPULATOR_SQUARE,	 /**< MANIPULATOR_SQUARE */
	MANIPULATOR_DIAMOND,	 /**< MANIPULATOR_DIAMOND */
	MANIPULATOR_CIRCLE,	 /**< MANIPULATOR_CIRCLE */
	MANIPULATOR_TRIANGLE,	 /**< MANIPULATOR_TRIANGLE */
	DOUBLE_OPEN_ARROW,	 /**< DOUBLE_OPEN_ARROW */
	WAVE					 /**< WAVE */
};

enum class PMICalloutFeatureAnnotationType
{
	FEATURETYPE_UNKNOWN = -1,							// No feature type
	FEATURETYPE_HOLE_UNKNOWN = 0,						//here feature hole is known then
	FEATURETYPE_HOLECALLOUTFIT,						/**< FEATURETYPE_HOLECALLOUTFIT */
	FEATURETYPE_HOLECALLOUTDEPTH,						/**< FEATURETYPE_HOLECALLOUTDEPTH */
	FEATURETYPE_HOLECALLOUTDIAMETER,					/**< FEATURETYPE_HOLECALLOUTDIAMETER */
	FEATURETYPE_HOLECALLOUTSCREWSIZE,					/**< FEATURETYPE_HOLECALLOUTSCREWSIZE */
	FEATURETYPE_HOLECALLOUTCOUNTERBOREDEPTH,			/**< FEATURETYPE_HOLECALLOUTCOUNTERBOREDEPTH */
	FEATURETYPE_HOLECALLOUTCOUNTERBOREDIAMETER,		/**< FEATURETYPE_HOLECALLOUTCOUNTERBOREDIAMETER */
	FEATURETYPE_HOLECALLOUTPATTERNCOUNT,				/**< FEATURETYPE_HOLECALLOUTPATTERNCOUNT,  >**/
	FEATURETYPE_HOLECALLOUTPITCH, //8					/**< FEATURETYPE_HOLECALLOUTPITCH, //8>**/	
	FEATURETYPE_HOLECALLOUTANGLE,						/**< FEATURETYPE_HOLECALLOUTANGLE,>**/
	FEATURETYPE_HOLECALLOUTPATTAPERANGLE,				/**< FEATURETYPE_HOLECALLOUTPATTAPERANGLE,>**/
	FEATURETYPE_HOLECALLOUTCOUNTERSINKDIAMETER,		/**< FEATURETYPE_HOLECALLOUTCOUNTERSINKDIAMETER,>**/
	FEATURETYPE_HOLECALLOUTPATCOUNTERSINKANGLE, //12	/**< FEATURETYPE_HOLECALLOUTPATCOUNTERSINKANGLE, //12>**/	
	FEATURETYPE_HOLECALLOUTTHREADDEPTH,				/**< FEATURETYPE_HOLECALLOUTTHREADDEPTH,>**/
	FEATURETYPE_HOLECALLOUTTHREADSIZE,				/**< FEATURETYPE_HOLECALLOUTTHREADSIZE,>**/
	FEATURETYPE_HOLECALLOUTTHREADMINORDIA,			/**< FEATURETYPE_HOLECALLOUTTHREADMINORDIA,>**/
	FEATURETYPE_HOLECALLOUTTHREADMAJORDIA,			/**< FEATURETYPE_HOLECALLOUTTHREADMAJORDIA>**/
	FEATURETYPE_HOLECALLOUTTAPDRILLDIA				/**< FEATURETYPE_HOLECALLOUTTAPDRILLDIA>**/
};

#define IS_InterOpPMIDimension(BasePtr) IS_DERIVED_SHARED_PTR(BasePtr, AMCAX::Exchange::InterOp::PMI::InterOpPMIDimension)
#define Cast_InterOpPMIDimension(BasePtr) SAFE_SHARED_PTR_CAST(BasePtr, AMCAX::Exchange::InterOp::PMI::InterOpPMIDimension)
class InterOpPMIDimension : public InterOpPMIAnnotation
{
public:
	PMIAnnotationType GetType() const override
	{
		return PMIAnnotationType::Dimension;
	} 
	
	void SetMainType(const PMIDimensionMainType &t){
		this->mainType = t ; 
	} ;
	void SetSubType(const PMIDimensionSubType &t){
		this->subType = t ; 
	} ;
	void SetCalloutFeatureAnnotationType(const PMICalloutFeatureAnnotationType &t){
		this->calloutFeatureAnnotationType = t ; 
	} ;
	void SetCoordValue(double x, double y, double z){
		this->coordValue[0] = x ; 
		this->coordValue[1] = y ; 
		this->coordValue[2] = z ; 
	} ;
	void SetTolerancePrecisionValue(double t){
		this->tolerancePrecisionValue = t ; 
	} ;
	void SetToleranceNumerialUpperValue(double t){
		this->toleranceNumerialUpperValue = t ; 
	} ;
	void SetToleranceNumerialLowerValue(double t){
		this->toleranceNumerialLowerValue = t ; 
	} ;
	void SetToleranceAlphanumericalUpperValue(const std::string &t){
		this->toleranceAlphanumericalUpperValue = t ; 
	} ;
	void SetToleranceAlphanumericalLowerValue(const std::string &t){
		this->toleranceAlphanumericalLowerValue = t ; 
	} ;
	void SetPrefixStr(const std::string &t){
		this->prefixStr = t ; 
	} ;
	void SetSuffixStr(const std::string &t){
		this->suffixStr = t ; 
	} ;
	void SetBeforeStr(const std::string &t){
		this->beforeStr = t ; 
	} ;
	void SetAfterStr(const std::string &t){
		this->afterStr = t ; 
	} ;
	void SetUpperStr(const std::string &t){
		this->upperStr = t ; 
	} ;
	void SetLowerStr(const std::string &t){
		this->lowerStr = t ; 
	} ;
	void SetHoleCalloutDimText(const std::string &t){
		this->holeCalloutDimText = t ; 
	} ;
	void SetBelowStr(const std::string &t){
		this->belowStr = t ; 
	} ;
	void SetNumbericalFakeValue(double t){
		this->numbericalFakeValue = t ; 
	} ;
	void SetAlphanumericalFakeValue(const std::string &t){
		this->alphanumericalFakeValue = t ; 
	} ;
	void SetIsDriving(bool t){
		this->isDriving = t ; 
	} ;
	void SetNote(const InterOpPMIText &t){
		this->note = t ; 
	} ;
	void SetHoleCalloutAlphanumericalValue(const std::string &t){
		this->holeCalloutAlphanumericalValue = t ; 
	} ;
	void SetLine2dStart(float x, float y){
		this->line2dStart[0] = x ; 
		this->line2dStart[1] = y ; 
	} ;
	void SetLine2dEnd(float x, float y){
		this->line2dEnd[0] = x ; 
		this->line2dEnd[1] = y ; 
	} ;
	void SetLine2dSymbolStart(const PMIArrowSymbol &t){
		this->line2dSymbolStart = t ; 
	} ;
	void SetLine2dSymbolEnd(const PMIArrowSymbol &t){
		this->line2dSymbolEnd = t ; 
	} ;
	void SetIsSymbolOutside(bool t){
		this->isSymbolOutside = t ; 
	} ;
	void SetDimensionValue(double t){
		this->dimensionValue = t ; 
	} ;
	void SetUnit(const PMIUnit &t){
		this->unit = t ; 
	} ;
	PMIDimensionMainType GetMainType() const {
		return mainType;
	}
	PMIDimensionSubType GetSubType() const {
		return subType;
	}
	PMICalloutFeatureAnnotationType GetCalloutFeatureAnnotationType() const {
		return calloutFeatureAnnotationType;
	}
	double GetDimensionValue() const {
		return dimensionValue;
	}
	PMIUnit GetUnit() const {
		return unit;
	}
	const double* GetCoordValue() const {
		return coordValue;
	}
	double GetTolerancePrecisionValue() const {
		return tolerancePrecisionValue;
	}
	double GetToleranceNumerialUpperValue() const {
		return toleranceNumerialUpperValue;
	}
	double GetToleranceNumerialLowerValue() const {
		return toleranceNumerialLowerValue;
	}
	const std::string& GetToleranceAlphanumericalUpperValue() const {
		return toleranceAlphanumericalUpperValue;
	}
	const std::string& GetToleranceAlphanumericalLowerValue() const {
		return toleranceAlphanumericalLowerValue;
	}
	const std::string& GetPrefixStr() const {
		return prefixStr;
	}
	const std::string& GetSuffixStr() const {
		return suffixStr;
	}
	const std::string& GetBeforeStr() const {
		return beforeStr;
	}
	const std::string& GetAfterStr() const {
		return afterStr;
	}
	const std::string& GetUpperStr() const {
		return upperStr;
	}
	const std::string& GetLowerStr() const {
		return lowerStr;
	}
	const std::string& GetHoleCalloutDimText() const {
		return holeCalloutDimText;
	}
	const std::string& GetBelowStr() const {
		return belowStr;
	}
	double GetNumbericalFakeValue() const {
		return numbericalFakeValue;
	}
	const std::string& GetAlphanumericalFakeValue() const {
		return alphanumericalFakeValue;
	}
	bool GetIsDriving() const {
		return isDriving;
	}
	const InterOpPMIText& GetNote() const {
		return note;
	}
	const std::string& GetHoleCalloutAlphanumericalValue() const {
		return holeCalloutAlphanumericalValue;
	}
	const float* GetLine2dStart() const {
		return line2dStart;
	}
	const float* GetLine2dEnd() const {
		return line2dEnd;
	}
	PMIArrowSymbol GetLine2dSymbolStart() const {
		return line2dSymbolStart;
	}
	PMIArrowSymbol GetLine2dSymbolEnd() const {
		return line2dSymbolEnd;
	}
	bool GetIsSymbolOutside() const {
		return isSymbolOutside;
	}
	
private:
	PMIDimensionMainType mainType ;
    PMIDimensionSubType subType ;
    PMICalloutFeatureAnnotationType calloutFeatureAnnotationType ;
	double dimensionValue ;
	PMIUnit unit ;
    double coordValue[3] ;
    double tolerancePrecisionValue ;
    double toleranceNumerialUpperValue ;
    double toleranceNumerialLowerValue ;
    std::string toleranceAlphanumericalUpperValue ;
    std::string toleranceAlphanumericalLowerValue ;
    std::string prefixStr ;
    std::string suffixStr ;
    std::string beforeStr ;
    std::string afterStr ;
    std::string upperStr ;
    std::string lowerStr ;
    std::string holeCalloutDimText ;
    std::string belowStr ;
    double numbericalFakeValue ;
    std::string alphanumericalFakeValue ;
    bool isDriving ;

    InterOpPMIText note ;
    std::string holeCalloutAlphanumericalValue ;
    // Obtain the dimension line of this dimension. Points are 2D and defined in the dimension owning view
    float line2dStart[2] ;
    float line2dEnd[2] ;
    PMIArrowSymbol line2dSymbolStart ;
    PMIArrowSymbol line2dSymbolEnd ;
    bool isSymbolOutside ;

} ;

}
#endif